package com.ctvit.sjk.knowledge.app.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctvit.sjk.knowledge.app.pojo.domain.TabAppChat;
import com.ctvit.sjk.knowledge.app.pojo.dto.AppChatMessageDTO;
import com.ctvit.sjk.knowledge.app.pojo.vo.AppChatMessageVO;
import com.ctvit.sjk.knowledge.app.pojo.domain.TabAppChatRecord;
import com.ctvit.sjk.knowledge.app.mapper.TabAppChatRecordMapper;
import com.ctvit.sjk.knowledge.app.service.ITabAppChatRecordService;
import com.ctvit.sjk.knowledge.app.service.ITabAppChatService;
import com.ctvit.sjk.knowledge.utils.SseMsgType;
import com.ctvit.sjk.knowledge.utils.SseServer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.ollama.OllamaChatClient;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

import java.time.LocalDateTime;

/**
 * 应用聊天记录Service业务层处理
 *
 * @author heyingcheng
 * @date 2025/3/22
 */
@Slf4j
@Service
public class TabAppChatRecordServiceImpl extends ServiceImpl<TabAppChatRecordMapper, TabAppChatRecord> implements ITabAppChatRecordService {

    private final OllamaChatClient ollamaChatClient;

    private final ITabAppChatService tabAppChatService;

    public TabAppChatRecordServiceImpl(OllamaChatClient ollamaChatClient, ITabAppChatService tabAppChatService) {
        this.ollamaChatClient = ollamaChatClient;
        this.tabAppChatService = tabAppChatService;
    }

    @Override
    public String message(String chatId, AppChatMessageDTO dto, String userId) {
        String recordId = IdWorker.getIdStr();
        String message = dto.getMessage();

        LambdaQueryWrapper<TabAppChatRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(TabAppChatRecord::getRecordIndex).orderByDesc(TabAppChatRecord::getRecordIndex).last("LIMIT 1");
        queryWrapper.eq(TabAppChatRecord::getChatId, chatId);
        TabAppChatRecord record = getOneOpt(queryWrapper, false).orElse(new TabAppChatRecord());

        int recordIndex = ObjectUtils.defaultIfNull(record.getRecordIndex(), 0) + 1;
        if (recordIndex == 1) {
            LambdaUpdateWrapper<TabAppChat> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(TabAppChat::getChatTitle, message.substring(0, Math.min(message.length(), 512)));
            updateWrapper.set(TabAppChat::getUpdateId, userId);
            updateWrapper.set(TabAppChat::getUpdateTime, LocalDateTime.now());
            updateWrapper.eq(TabAppChat::getChatId, chatId);
            tabAppChatService.update(updateWrapper);
        }

        // 创建聊天记录
        TabAppChatRecord entity = new TabAppChatRecord();
        entity.setRecordId(recordId);
        entity.setChatId(chatId);
        entity.setRecordIndex(recordIndex);
        entity.setProblemText(message);
        entity.setAnswerText(StringUtils.EMPTY);
        entity.setDetails(JSON.toJSONString(new JSONObject()));
        entity.setImproveParagraphIdList(JSON.toJSONString(new JSONArray()));
        entity.setAnswerTextList(JSON.toJSONString(new JSONArray()));
        entity.setCreateTime(LocalDateTime.now());
        entity.setUpdateTime(LocalDateTime.now());
        save(entity);

        Prompt prompt = new Prompt(new UserMessage(message));
        Flux<ChatResponse> streamResponse = ollamaChatClient.stream(prompt);

        String answerText = StringUtils.joinWith(StringUtils.EMPTY, streamResponse.toStream().map(chatResponse -> {
            String content = chatResponse.getResult().getOutput().getContent();
            AppChatMessageVO appChatMessageVO = getAppChatMessage(chatId, userId, recordId, content, false);
            SseServer.sendMessage(userId, JSON.toJSONString(appChatMessageVO), SseMsgType.DATA);
            return content;
        }).toArray());

        AppChatMessageVO appChatMessageVO = getAppChatMessage(chatId, userId, recordId, StringUtils.EMPTY, true);
        SseServer.sendMessage(userId, JSON.toJSONString(appChatMessageVO), SseMsgType.DATA);

        // 更新聊天记录
        LambdaUpdateWrapper<TabAppChatRecord> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(TabAppChatRecord::getAnswerText, answerText);
        updateWrapper.set(TabAppChatRecord::getUpdateTime, LocalDateTime.now());

        JSONArray answerTextList = new JSONArray();
        answerTextList.add(getAnswerTextJsonArray(answerText));
        updateWrapper.set(TabAppChatRecord::getAnswerTextList, JSON.toJSONString(answerTextList));

        updateWrapper.eq(TabAppChatRecord::getRecordId, recordId);
        update(updateWrapper);

        return StringUtils.EMPTY;
    }

    private JSONArray getAnswerTextJsonArray(String answerText) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("content", answerText);
        jsonObject.put("view_type", "ai-chat-node");
        jsonObject.put("child_node", new JSONObject());
        jsonObject.put("real_node_id", "ai-chat-node");
        jsonObject.put("chat_record_id", "ai-chat-node");
        jsonObject.put("runtime_node_id", "ai-chat-node");
        jsonObject.put("reasoning_content", "");

        JSONArray jsonArray = new JSONArray();
        jsonArray.add(jsonObject);
        return jsonArray;
    }

    private static AppChatMessageVO getAppChatMessage(String chatId, String userId, String recordId, String content, Boolean isEnd) {
        AppChatMessageVO appChatMessageVO = new AppChatMessageVO();
        appChatMessageVO.setChatId(chatId);
        appChatMessageVO.setChatRecordId(recordId);
        appChatMessageVO.setOperate(true);
        appChatMessageVO.setContent(content);
        appChatMessageVO.setNodeId("ai-chat-node");
        appChatMessageVO.setNodeType("ai-chat-node");
        appChatMessageVO.setRealNodeId("ai-chat-node");
        appChatMessageVO.setViewType("many_view");
        appChatMessageVO.setUpNodeIdList(new JSONArray());
        appChatMessageVO.setIsEnd(isEnd);
        appChatMessageVO.setNodeIsEnd(isEnd);
        appChatMessageVO.setUsage(JSON.parseObject("{\"completion_tokens\": 0, \"prompt_tokens\": 0, \"total_tokens\": 0}"));
        appChatMessageVO.setReasoningContent(StringUtils.EMPTY);
        return appChatMessageVO;
    }

}
